using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GameStateManagement;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input.Touch;
using Microsoft.Xna.Framework.Graphics;
using GameStateManagementSample.QuickMath;

namespace GameStateManagementSample.Screens
{
    class Screen_QuickMath : GameScreen
    {
#region Fields
        ContentManager m_Content;
        InputAction pauseAction;
        Circle m_Circle;
        SliderMath m_Slider1,m_Slider2,m_Slider3;
        Texture2D m_TexBack;
        bool iOther=false;
        Random m_Random;
        float m_TimeGame;
        SpriteFont m_Font;
        int m_Level;
#endregion
        
#region Initialization
        public Screen_QuickMath(int _level)
        {
            TransitionOnTime = TimeSpan.FromSeconds(0.5f);
            TransitionOffTime = TimeSpan.FromSeconds(0.5f);
            pauseAction = new InputAction(
                new Buttons[] { Buttons.Start, Buttons.Back },
                new Keys[] { Keys.Escape },
                true);
            m_Level = _level;
            Level.Cur = _level;
        }
        public override void Activate(bool instancePreserved)
        {
            if (!instancePreserved)
            {
                if (m_Content == null)
                {
                    m_Content = new ContentManager(ScreenManager.Game.Services, "Content");
                    ScreenManager.Game.ResetElapsedTime();
                    m_Circle = new Circle(600, 280, 170, ScreenManager);

                    m_TexBack = m_Content.Load<Texture2D>(@"Image/backgame");
                    
                    Texture2D m_TexSlider = m_Content.Load<Texture2D>(@"Image/oo");

                    m_Font = m_Content.Load<SpriteFont>("gamefont");

                    m_Slider1 = new SliderMath(0, m_TexSlider, m_Font);
                    m_Slider2 = new SliderMath(120, m_TexSlider, m_Font);
                    m_Slider3 = new SliderMath(240, m_TexSlider, m_Font);

                    m_Random = new Random();

                    InitLevel(m_Level);
                }
            }
        }
        public override void Deactivate()
        {
            base.Deactivate();
        }
        public override void Unload()
        {
            base.Unload();
        }
#endregion
        #region Update and Draw
        protected virtual void OnCancel() 
        {
            
        }
        public override void Update(Microsoft.Xna.Framework.GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen)
        {
            base.Update(gameTime, otherScreenHasFocus, false);
            iOther = otherScreenHasFocus;
            if (!otherScreenHasFocus)
            {
                m_Circle.Update(gameTime);
                m_Slider1.Update(gameTime);
                m_Slider2.Update(gameTime);
                m_Slider3.Update(gameTime);
                m_TimeGame -= (float)gameTime.ElapsedGameTime.TotalSeconds;
                if (iCheckLose())
                {
                    ScreenManager.AddScreen(new Screen_Lose(), null);
                }
            }
           
        }
        public override void HandleInput(Microsoft.Xna.Framework.GameTime gameTime, InputState input)
        {
            if (input == null)
            {
                throw new ArgumentNullException("input");
            }
            PlayerIndex player;
            if (pauseAction.Evaluate(input,ControllingPlayer,out player))
            {
                foreach (GameScreen screen in ScreenManager.GetScreens())
                {
                    screen.ExitScreen();
                }
                ScreenManager.AddScreen(new Screen_Menu(), null);
            }
            TouchCollection touches = input.TouchState;
            
            foreach (TouchLocation touch in touches)
            {
                if (touch.State == TouchLocationState.Pressed)
                {
                    Vector2 dis = touch.Position - m_Circle.Center;
                    if (dis.Length() < 49) TouchButtonOK();
                }
            }
            m_Circle.InputTouch(touches);
            m_Slider1.InputTouch(touches);
            m_Slider2.InputTouch(touches);
            m_Slider3.InputTouch(touches);
        }
        public override void Draw(Microsoft.Xna.Framework.GameTime gameTime)
        {
            SpriteBatch spriteBatch = ScreenManager.SpriteBatch;

            spriteBatch.Begin();
            spriteBatch.Draw(m_TexBack, new Vector2(TransitionPosition*800,0), Color.White);
            if (TransitionPosition == 0)
            {
                m_Slider1.Draw(spriteBatch);
                m_Slider2.Draw(spriteBatch);
                m_Slider3.Draw(spriteBatch);
            }
            spriteBatch.DrawString(m_Font, "Time:" + m_TimeGame.ToString("00"), new Vector2(400 + TransitionPosition * 800, 20), Color.White);

            spriteBatch.DrawString(m_Font, "Level:" + m_Level.ToString(), new Vector2(600 + TransitionPosition * 800, 20), Color.White);
            spriteBatch.End();
            if (TransitionPosition ==0)
            {
                m_Circle.Draw();
            }
            
            if (iOther)
            {
                float alpha = MathHelper.Lerp(1f - TransitionAlpha, 1f, TransitionAlpha / 2);

                ScreenManager.FadeBackBufferToBlack(alpha);
            }
        }
        public void DrawSlider(SpriteBatch _sb)
        {
            _sb.DrawString(ScreenManager.Font,m_Slider1.OperatorSelect().ToString(), new Vector2(650, 2), Color.White);
            _sb.DrawString(ScreenManager.Font, m_Circle.OperatorSelect().ToString(), new Vector2(700, 2), Color.White);
        }
        #endregion
#region Quickmath
        /************************************************************************/
        /* iAdd,iSub,iMulti,iDivi = 0 No use
         * >0 num use
         * <0 random         
        /************************************************************************/
        public void CreateQuickMath(int _NumQuestion, int _NumAnswer,int _Limit, int _iAdd, int _iSub, int _iMulti,int _iDivi)
        {
            while (_NumAnswer>0 || _NumQuestion >0)
            {
                _NumAnswer--;
                _NumQuestion--;
                int oper1 = _Limit, oper2 = -1, oper3 = _Limit, result = _Limit;

                while (oper2 <0)
                {
                    int r = m_Random.Next(4);
#region Tao tu toan
                    switch (r)
                    {
                        // Phep cong
                        case 0:
                            if (_iAdd != 0)
                            {
                                _iAdd--;// Thuc hien 1 phep cong
                                oper2 = 0;// Xac dinh phep cong
                                do
                                {
                                    oper3 = m_Random.Next(_Limit * 2) - _Limit;
                                    oper1 = m_Random.Next(_Limit * 2) - _Limit; // Tu toan 1 co gia tri tu -limit den limit

                                    

                                    result = oper1 + oper3;
                                } while (result > _Limit || result < -_Limit);
                            }
                            break;
                        // Phep tru
                        case 1:
                            if (_iSub!=0 )
                            {
                                _iSub--;
                                oper2 = 1;
                                do
                                {
                                    oper1 = m_Random.Next(_Limit * 2) - _Limit; // Tu toan 1 co gia tri tu -limit den limit

                                    oper3 = m_Random.Next(_Limit * 2) - _Limit;

                                    result = oper1 - oper3;
                                } while (result > _Limit || result < -_Limit);
                            }
                            break;
                        // Phep nhan
                        case 2:
                            if (_iMulti != 0)
                            {
                                _iMulti--;
                                oper2 = 2;
                                do
                                {
                                    oper1 = m_Random.Next(_Limit ) - _Limit/2; // Tu toan 1 co gia tri tu -limit den limit

                                    oper3 = m_Random.Next(_Limit ) - _Limit/2;

                                    result = oper1 * oper3;
                                } while (result > _Limit || result < -_Limit);
                            }
                            break;
                        // phep chia
                        case 3:
                            if (_iDivi != 0)
                            {
                                _iDivi--;
                                oper2 = 3;
                                do
                                {
                                    result = m_Random.Next(_Limit * 2) - _Limit; // Tu toan 1 co gia tri tu -limit den limit

                                    oper3 = m_Random.Next(_Limit * 2) - _Limit;

                                    oper1 = result*oper3;
                                } while (oper1 > _Limit || oper1 < -_Limit || oper3 ==0);
                            }
                            break;
                    }
#endregion
                }
#region Copy sang cac slider va circle

                int pos1,pos2,pos3, pos4;
                do
                {
                    pos1 = m_Random.Next(800);
                    pos1 = pos1 % 8;
                }
                while (m_Slider1.m_Operator[pos1].m_First != MyOperator.type.Empty);
                
                do
                {
                    pos2 = m_Random.Next(800);
                    pos2 = pos2 % 8;
                } while (m_Slider2.m_Operator[pos2].m_First != MyOperator.type.Empty);
                
                do
                {
                    pos3 = m_Random.Next(800);
                    pos3 = pos3 % 8;
                } while (m_Slider3.m_Operator[pos3].m_First != MyOperator.type.Empty);
                
                do
                {
                    pos4 = m_Random.Next(800);
                    pos4 = pos4 % 8;
                } while (m_Circle.m_Operator[pos4].m_First != MyOperator.type.Empty);
                

                m_Slider1.m_Operator[pos1].m_First = MyOperator.type.Number;
                m_Slider1.m_Operator[pos1].m_Sec = oper1;

                
                m_Slider2.m_Operator[pos2].m_First = MyOperator.type.Operation;
                m_Slider2.m_Operator[pos2].m_Sec = oper2;

                
                m_Slider3.m_Operator[pos3].m_First = MyOperator.type.Number;
                m_Slider3.m_Operator[pos3].m_Sec = oper3;

                if (_NumAnswer >= 0)
                {
                    m_Circle.m_Operator[pos4].m_First = MyOperator.type.Number;
                    m_Circle.m_Operator[pos4].m_Sec = result;
                }
                
            }
#endregion

        }
        public void InitLevel(int _level)
        {
            int i = _level*Level.col;
            m_TimeGame = Level.level[i + 7];
            CreateQuickMath(Level.level[i + 0], Level.level[i + 1], Level.level[i + 2], Level.level[i + 3], Level.level[i + 4], Level.level[i + 5], Level.level[i + 6]);
        }
        public bool iCheckSelectMath()
        {
            if (m_Slider1.OperatorSelect().m_First != MyOperator.type.Number || 
                m_Slider2.OperatorSelect().m_First != MyOperator.type.Operation||
                m_Slider3.OperatorSelect().m_First != MyOperator.type.Number||
                m_Circle.OperatorSelect().m_First != MyOperator.type.Number)
            {
                return false;
            }
            int Num1 = m_Slider1.OperatorSelect().m_Sec;
            int Num2 = m_Slider3.OperatorSelect().m_Sec;
            int Num3 = 0;
            switch (m_Slider2.OperatorSelect().m_Sec)
            {
                case 0:
                    Num3 = Num1 + Num2;
                    break;
                case 1:
                    Num3 = Num1 - Num2;
                    break;
                case 2:
                    Num3 = Num1 * Num2;
                    break;
                case 3:
                    if (Num2 == 0) return false;                   
                    if (Num1 % Num2 != 0) return false; // neu phep chia du thi ket qua la false 
                    Num3 = Num1 / Num2;
                    break;
            }
            if (Num3 == m_Circle.OperatorSelect().m_Sec)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        public void TouchButtonOK()
        {
            if (iCheckSelectMath())
            {
                m_Slider1.OperatorSelect().m_First = MyOperator.type.OK;
                m_Slider2.OperatorSelect().m_First = MyOperator.type.OK;
                m_Slider3.OperatorSelect().m_First = MyOperator.type.OK;
                m_Circle.OperatorSelect().m_First = MyOperator.type.OK;
                if (iCheckWin())
                {
                    ScreenManager.AddScreen(new Screen_Win(), null);
                }
            }
        }
        public bool iCheckWin()
        {
            bool result = true;
            foreach (MyOperator oper in m_Circle.m_Operator)
            {
                if (oper.m_First == MyOperator.type.Number)
                {
                    result = false;
                }
            }
            return result;
        }
        public bool iCheckLose()
        {
            if (m_TimeGame<0)
            {
                return true;
            }
            return false;
        }
#endregion
    }
}
